package com.scnu.edu.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.scnu.edu.entity.Order;
import com.scnu.edu.entity.User;
import com.scnu.edu.mapper.OrderMapper;
import com.scnu.edu.service.OrderService;
import com.scnu.edu.service.UserService;
import jakarta.annotation.Resource;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.math.BigDecimal;
import java.time.LocalDate;
import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;
import java.util.*;
import java.util.stream.Collectors;

@Service
public class OrderServiceImpl extends ServiceImpl<OrderMapper, Order> implements OrderService {

    @Resource
    private UserService userService;

    private static final BigDecimal DAILY_VIP_PRICE = new BigDecimal("0.50");

    @Override
    public Order createVipOrder(Integer userId, Integer days) {
        Order order = new Order();
        order.setUserId(Long.valueOf(userId));
        order.setPayType(2);
        order.setVipDays(days);
        order.setAmount(DAILY_VIP_PRICE.multiply(new BigDecimal(days)));
        order.setStatus(0);
        order.setCreateTime(new Date());
        order.setOrderNo(generateOrderNo());

        this.save(order);
        return order;
    }

    @Override
    @Transactional
    public boolean handlePaymentSuccess(Integer orderId) {
        Order order = this.getById(orderId);
        if (order == null || order.getStatus() != 0) {
            return false;
        }

        // 更新订单状态
        order.setStatus(1);
        order.setPayTime(new Date());
        boolean updated = this.updateById(order);

        if (updated) {
            // 更新用户VIP状态
            User user = userService.updateVipStatus(order.getUserId(), order.getVipDays());
            return user != null; // 返回操作是否成功
        }

        return false;
    }

    @Override
    public Map<String, Object> getOrderStats(String type) {
        LocalDateTime now = LocalDateTime.now();
        LocalDateTime startTime;
        String format;

        switch (type.toLowerCase()) {
            case "weekly":
                startTime = now.minusWeeks(1);
                format = "MM-dd";
                break;
            case "monthly":
                startTime = now.minusMonths(1);
                format = "MM-dd";
                break;
            case "yearly":
                startTime = now.minusYears(1);
                format = "yyyy-MM";
                break;
            default:
                throw new IllegalArgumentException("Invalid stats type");
        }

        // 查询订单数据
        LambdaQueryWrapper<Order> wrapper = new LambdaQueryWrapper<>();
        wrapper.ge(Order::getCreateTime, Date.from(startTime.atZone(java.time.ZoneId.systemDefault()).toInstant()))
                .le(Order::getCreateTime, new Date())
                .eq(Order::getStatus, "completed");

        List<Order> orders = this.list(wrapper);

        // 按日期分组统计
        DateTimeFormatter formatter = DateTimeFormatter.ofPattern(format);
        Map<String, List<Order>> groupedOrders = orders.stream()
                .collect(Collectors.groupingBy(order -> {
                    LocalDateTime orderTime = LocalDateTime.ofInstant(
                            order.getCreateTime().toInstant(),
                            java.time.ZoneId.systemDefault());
                    return orderTime.format(formatter);
                }));

        // 构建统计结果
        Map<String, Object> result = new HashMap<>();
        List<String> dates = new ArrayList<>();
        List<Integer> counts = new ArrayList<>();
        List<BigDecimal> amounts = new ArrayList<>();

        // 填充日期范围内的所有日期
        LocalDate date = startTime.toLocalDate();
        while (!date.isAfter(now.toLocalDate())) {
            String dateStr = date.format(formatter);
            dates.add(dateStr);
            List<Order> dateOrders = groupedOrders.getOrDefault(dateStr, Collections.emptyList());
            counts.add(dateOrders.size());
            amounts.add(dateOrders.stream()
                    .map(Order::getAmount)
                    .reduce(BigDecimal.ZERO, BigDecimal::add));
            date = type.equals("yearly") ? date.plusMonths(1) : date.plusDays(1);
        }

        result.put("dates", dates);
        result.put("counts", counts);
        result.put("amounts", amounts);
        return result;
    }

    @Override
    public Map<String, Object> getUserOrders(Integer userId, Integer pageNo, Integer pageSize) {
        LambdaQueryWrapper<Order> wrapper = new LambdaQueryWrapper<>();
        wrapper.eq(Order::getUserId, userId)
                .orderByDesc(Order::getCreateTime);

        IPage<Order> page = new Page<>(pageNo, pageSize);
        page = this.page(page, wrapper);

        Map<String, Object> result = new HashMap<>();
        result.put("records", page.getRecords());
        result.put("total", page.getTotal());
        result.put("pageCount", page.getPages());
        return result;
    }

    private String generateOrderNo() {
        // 生成订单号：时间戳 + 4位随机数
        return LocalDateTime.now().format(DateTimeFormatter.ofPattern("yyyyMMddHHmmss")) +
                String.format("%04d", new Random().nextInt(10000));
    }
}